﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Acoris.Models
{
    using System;
    using System.Windows.Input;

    public delegate bool CanExecuteHandler(object param);
    public delegate void ExecuteHandler(object param);

    public sealed class DelegateCommand : ICommand
    {
        #region Fields

        private CanExecuteHandler _canExecute;
        private ExecuteHandler _execute;

        #endregion

        #region Constructor

        private DelegateCommand(CanExecuteHandler canExecute,ExecuteHandler execute)
        {
            _canExecute = canExecute ?? throw new NullReferenceException();
            _execute = execute ?? throw new NullReferenceException();
        }

        #endregion

        #region Method

        public event EventHandler CanExecuteChanged{
            add{
                CommandManager.RequerySuggested += value;
            }
            remove{
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        #endregion

        static bool InternalTrueCanExecuteHandler(object param) => true;

        /// <summary>
        /// 创建不检查执行状态的代理命令
        /// </summary>
        /// <param name="handler">ExecuteHandler委托</param>
        /// <returns>返回创建的新代理命令</returns>
        public static DelegateCommand Create(ExecuteHandler handler)
        {
            return new DelegateCommand(InternalTrueCanExecuteHandler, handler);
        }

        /// <summary>
        /// 指定检查执行状态的委托方法以及执行操作的委托方法创建代理命令
        /// </summary>
        /// <param name="canExecute"></param>
        /// <param name="execute"></param>
        /// <returns></returns>
        public static DelegateCommand Create(CanExecuteHandler canExecute,ExecuteHandler execute)
        {
            return new DelegateCommand(canExecute, execute);
        }
    }
}
